package qos.estimator.statistics;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.concurrent.Semaphore;

import qos.estimator.exception.CollectorException;

public class DiskStatisticsCollector implements IStatisticsCollector {

	private Double diskUsage = 0d;
	private Semaphore semaphore = new Semaphore(1);
	private boolean forceStop = false;
	public DiskStatisticsCollector() {
		new Thread(new Runnable(){

			public void run() {
				try {
					
					Process process = Runtime.getRuntime().exec("iostat -k sda 5");
					java.io.BufferedReader in = new java.io.BufferedReader(new java.io.InputStreamReader(process.getInputStream()));
					String line = null;  
					Double newDiskUsage = 0d;
					while ((line = in.readLine()) != null) {
						if(forceStop)
							return;
						if(line.startsWith("sda ")){
							semaphore.acquire();
							newDiskUsage = 0d;
							StringTokenizer st = new StringTokenizer(line, " ");
							//Discarding the first two tokens
							st.nextElement();
							st.nextElement();
							while (st.hasMoreTokens()) {
								String usage = st.nextToken();
								newDiskUsage += Double.parseDouble(usage.replace(",", "."));
							}
						}else{
							diskUsage = newDiskUsage;
							semaphore.release();
						}
					}
				} catch (IOException e) {
					e.printStackTrace();
					diskUsage = -1d;
				} catch (InterruptedException e) {
					e.printStackTrace();
				} finally{
					semaphore.release();
				}
			}
			
			
		}).start();
	}
	

	public Map<String, Double> next() throws CollectorException {
		try {
			semaphore.acquire();
			if(diskUsage == -1){
				throw new CollectorException("Could not read disk statistics. Service started?");
			}
			Map<String, Double> nonVolatileMap = new HashMap<String, Double>();
			
			//is this really necessary??
			nonVolatileMap.put("diskUsage", new Double(diskUsage));
			return nonVolatileMap;
		} catch (InterruptedException e) {
			throw new CollectorException(e);
		} finally{
			semaphore.release();
		}
		
	}
	
	
	public void forceStop(){
		forceStop = true;
	}
	
	

}
